// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.core.skinnedmodel.population;

import java.util.ArrayList;
import java.util.Locale;
import zombie.characters.IsoGameCharacter;
import zombie.characters.WornItems.BodyLocationGroup;
import zombie.core.ImmutableColor;
import zombie.core.skinnedmodel.ModelManager;
import zombie.core.skinnedmodel.model.CharacterMask;
import zombie.core.skinnedmodel.model.ModelInstance;
import zombie.core.skinnedmodel.visual.HumanVisual;
import zombie.core.skinnedmodel.visual.IHumanVisual;
import zombie.core.skinnedmodel.visual.ItemVisual;
import zombie.core.skinnedmodel.visual.ItemVisuals;
import zombie.debug.DebugLog;
import zombie.debug.DebugType;
import zombie.scripting.objects.Item;
import zombie.util.StringUtils;

public class PopTemplateManager {
    public static final PopTemplateManager instance = new PopTemplateManager();
    public final ArrayList<String> m_MaleSkins = new ArrayList();
    public final ArrayList<String> m_FemaleSkins = new ArrayList();
    public final ArrayList<String> m_MaleSkins_Zombie1 = new ArrayList();
    public final ArrayList<String> m_FemaleSkins_Zombie1 = new ArrayList();
    public final ArrayList<String> m_MaleSkins_Zombie2 = new ArrayList();
    public final ArrayList<String> m_FemaleSkins_Zombie2 = new ArrayList();
    public final ArrayList<String> m_MaleSkins_Zombie3 = new ArrayList();
    public final ArrayList<String> m_FemaleSkins_Zombie3 = new ArrayList();
    public final ArrayList<String> m_SkeletonMaleSkins_Zombie = new ArrayList();
    public final ArrayList<String> m_SkeletonFemaleSkins_Zombie = new ArrayList();
    public static final int SKELETON_BURNED_SKIN_INDEX = 0;
    public static final int SKELETON_NORMAL_SKIN_INDEX = 1;
    public static final int SKELETON_MUSCLE_SKIN_INDEX = 2;

    public void init() {
        ItemManager.init();

        for (int int0 = 1; int0 <= 5; int0++) {
            this.m_MaleSkins.add("MaleBody0" + int0);
        }

        for (int int1 = 1; int1 <= 5; int1++) {
            this.m_FemaleSkins.add("FemaleBody0" + int1);
        }

        for (int int2 = 1; int2 <= 4; int2++) {
            this.m_MaleSkins_Zombie1.add("M_ZedBody0" + int2 + "_level1");
            this.m_FemaleSkins_Zombie1.add("F_ZedBody0" + int2 + "_level1");
            this.m_MaleSkins_Zombie2.add("M_ZedBody0" + int2 + "_level2");
            this.m_FemaleSkins_Zombie2.add("F_ZedBody0" + int2 + "_level2");
            this.m_MaleSkins_Zombie3.add("M_ZedBody0" + int2 + "_level3");
            this.m_FemaleSkins_Zombie3.add("F_ZedBody0" + int2 + "_level3");
        }

        this.m_SkeletonMaleSkins_Zombie.add("SkeletonBurned");
        this.m_SkeletonMaleSkins_Zombie.add("Skeleton");
        this.m_SkeletonMaleSkins_Zombie.add("SkeletonMuscle");
        this.m_SkeletonFemaleSkins_Zombie.add("SkeletonBurned");
        this.m_SkeletonFemaleSkins_Zombie.add("Skeleton");
        this.m_SkeletonFemaleSkins_Zombie.add("SkeletonMuscle");
    }

    public ModelInstance addClothingItem(IsoGameCharacter chr, ModelManager.ModelSlot modelSlot, ItemVisual itemVisual, ClothingItem clothingItem) {
        String string0 = clothingItem.getModel(chr.isFemale());
        if (StringUtils.isNullOrWhitespace(string0)) {
            if (DebugLog.isEnabled(DebugType.Clothing)) {
                DebugLog.Clothing.debugln("No model specified by item: " + clothingItem.m_Name);
            }

            return null;
        } else {
            string0 = this.processModelFileName(string0);
            String string1 = itemVisual.getTextureChoice(clothingItem);
            ImmutableColor immutableColor = itemVisual.getTint(clothingItem);
            float _float = itemVisual.getHue(clothingItem);
            String string2 = clothingItem.m_AttachBone;
            String string3 = clothingItem.m_Shader;
            ModelInstance modelInstance;
            if (string2 != null && string2.length() > 0) {
                modelInstance = ModelManager.instance.newStaticInstance(modelSlot, string0, string1, string2, string3);
            } else {
                modelInstance = ModelManager.instance.newAdditionalModelInstance(string0, string1, chr, modelSlot.model.AnimPlayer, string3);
            }

            if (modelInstance == null) {
                return null;
            } else {
                this.postProcessNewItemInstance(modelInstance, modelSlot, immutableColor);
                modelInstance.setItemVisual(itemVisual);
                return modelInstance;
            }
        }
    }

    private void addHeadHairItem(
        IsoGameCharacter isoGameCharacter, ModelManager.ModelSlot modelSlot, String string0, String string1, ImmutableColor immutableColor
    ) {
        if (StringUtils.isNullOrWhitespace(string0)) {
            if (DebugLog.isEnabled(DebugType.Clothing)) {
                DebugLog.Clothing.warn("No model specified.");
            }
        } else {
            string0 = this.processModelFileName(string0);
            ModelInstance modelInstance = ModelManager.instance
                .newAdditionalModelInstance(string0, string1, isoGameCharacter, modelSlot.model.AnimPlayer, null);
            if (modelInstance != null) {
                this.postProcessNewItemInstance(modelInstance, modelSlot, immutableColor);
            }
        }
    }

    private void addHeadHair(
        IsoGameCharacter isoGameCharacter, ModelManager.ModelSlot modelSlot, HumanVisual humanVisual, ItemVisual itemVisual, boolean _boolean
    ) {
        ImmutableColor immutableColor = humanVisual.getHairColor();
        if (_boolean) {
            immutableColor = humanVisual.getBeardColor();
        }

        if (isoGameCharacter.isFemale()) {
            if (!_boolean) {
                HairStyle hairStyle0 = HairStyles.instance.FindFemaleStyle(humanVisual.getHairModel());
                if (hairStyle0 != null && itemVisual != null && itemVisual.getClothingItem() != null) {
                    hairStyle0 = HairStyles.instance.getAlternateForHat(hairStyle0, itemVisual.getClothingItem().m_HatCategory);
                }

                if (hairStyle0 != null && hairStyle0.isValid()) {
                    if (DebugLog.isEnabled(DebugType.Clothing)) {
                        DebugLog.Clothing.debugln("  Adding female hair: " + hairStyle0.name);
                    }

                    this.addHeadHairItem(isoGameCharacter, modelSlot, hairStyle0.model, hairStyle0.texture, immutableColor);
                }
            }
        } else if (!_boolean) {
            HairStyle hairStyle1 = HairStyles.instance.FindMaleStyle(humanVisual.getHairModel());
            if (hairStyle1 != null && itemVisual != null && itemVisual.getClothingItem() != null) {
                hairStyle1 = HairStyles.instance.getAlternateForHat(hairStyle1, itemVisual.getClothingItem().m_HatCategory);
            }

            if (hairStyle1 != null && hairStyle1.isValid()) {
                if (DebugLog.isEnabled(DebugType.Clothing)) {
                    DebugLog.Clothing.debugln("  Adding male hair: " + hairStyle1.name);
                }

                this.addHeadHairItem(isoGameCharacter, modelSlot, hairStyle1.model, hairStyle1.texture, immutableColor);
            }
        } else {
            BeardStyle beardStyle = BeardStyles.instance.FindStyle(humanVisual.getBeardModel());
            if (beardStyle != null && beardStyle.isValid()) {
                if (itemVisual != null
                    && itemVisual.getClothingItem() != null
                    && !StringUtils.isNullOrEmpty(itemVisual.getClothingItem().m_HatCategory)
                    && itemVisual.getClothingItem().m_HatCategory.contains("nobeard")) {
                    return;
                }

                if (DebugLog.isEnabled(DebugType.Clothing)) {
                    DebugLog.Clothing.debugln("  Adding beard: " + beardStyle.name);
                }

                this.addHeadHairItem(isoGameCharacter, modelSlot, beardStyle.model, beardStyle.texture, immutableColor);
            }
        }
    }

    public void populateCharacterModelSlot(IsoGameCharacter chr, ModelManager.ModelSlot modelSlot) {
        if (!(chr instanceof IHumanVisual)) {
            DebugLog.Clothing.warn("Supplied character is not an IHumanVisual. Ignored. " + chr);
        } else {
            HumanVisual humanVisual = ((IHumanVisual)chr).getHumanVisual();
            ItemVisuals itemVisuals = new ItemVisuals();
            chr.getItemVisuals(itemVisuals);
            CharacterMask characterMask = HumanVisual.GetMask(itemVisuals);
            if (DebugLog.isEnabled(DebugType.Clothing)) {
                DebugLog.Clothing.debugln("characterType:" + chr.getClass().getName() + ", name:" + chr.getName());
            }

            if (characterMask.isPartVisible(CharacterMask.Part.Head)) {
                this.addHeadHair(chr, modelSlot, humanVisual, itemVisuals.findHat(), false);
                this.addHeadHair(chr, modelSlot, humanVisual, itemVisuals.findMask(), true);
            }

            for (int int0 = itemVisuals.size() - 1; int0 >= 0; int0--) {
                ItemVisual itemVisual0 = (ItemVisual)itemVisuals.get(int0);
                ClothingItem clothingItem0 = itemVisual0.getClothingItem();
                if (clothingItem0 == null) {
                    if (DebugLog.isEnabled(DebugType.Clothing)) {
                        DebugLog.Clothing.warn("ClothingItem not found for ItemVisual:" + itemVisual0);
                    }
                } else if (!this.isItemModelHidden(chr.getBodyLocationGroup(), itemVisuals, itemVisual0)) {
                    this.addClothingItem(chr, modelSlot, itemVisual0, clothingItem0);
                }
            }

            for (int int1 = humanVisual.getBodyVisuals().size() - 1; int1 >= 0; int1--) {
                ItemVisual itemVisual1 = (ItemVisual)humanVisual.getBodyVisuals().get(int1);
                ClothingItem clothingItem1 = itemVisual1.getClothingItem();
                if (clothingItem1 == null) {
                    if (DebugLog.isEnabled(DebugType.Clothing)) {
                        DebugLog.Clothing.warn("ClothingItem not found for ItemVisual:" + itemVisual1);
                    }
                } else {
                    this.addClothingItem(chr, modelSlot, itemVisual1, clothingItem1);
                }
            }

            chr.postUpdateModelTextures();
            chr.updateSpeedModifiers();
        }
    }

    public boolean isItemModelHidden(BodyLocationGroup bodyLocationGroup, ItemVisuals visuals, ItemVisual visual) {
        Item item0 = visual.getScriptItem();
        if (item0 != null && bodyLocationGroup.getLocation(item0.getBodyLocation()) != null) {
            for (int _int = 0; _int < visuals.size(); _int++) {
                if (visuals.get(_int) != visual) {
                    Item item1 = ((ItemVisual)visuals.get(_int)).getScriptItem();
                    if (item1 != null
                        && bodyLocationGroup.getLocation(item1.getBodyLocation()) != null
                        && bodyLocationGroup.isHideModel(item1.getBodyLocation(), item0.getBodyLocation())) {
                        return true;
                    }
                }
            }

            return false;
        } else {
            return false;
        }
    }

    private String processModelFileName(String string) {
        string = string.replaceAll("\\\\", "/");
        return string.toLowerCase(Locale.ENGLISH);
    }

    private void postProcessNewItemInstance(ModelInstance modelInstance, ModelManager.ModelSlot modelSlot, ImmutableColor immutableColor) {
        modelInstance.depthBias = 0.0F;
        modelInstance.matrixModel = modelSlot.model;
        modelInstance.tintR = immutableColor.r;
        modelInstance.tintG = immutableColor.g;
        modelInstance.tintB = immutableColor.b;
        modelInstance.parent = modelSlot.model;
        modelInstance.AnimPlayer = modelSlot.model.AnimPlayer;
        modelSlot.model.sub.add(0, modelInstance);
        modelSlot.sub.add(0, modelInstance);
        modelInstance.setOwner(modelSlot);
    }
}
